package cn.edu.xmu.oomall.customer.service;

import cn.edu.xmu.oomall.core.util.Common;
import cn.edu.xmu.oomall.core.model.VoObject;
import cn.edu.xmu.oomall.core.util.JacksonUtil;
import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.customer.microservice.CouponActivityService;
import cn.edu.xmu.oomall.customer.microservice.GoodsService;
import cn.edu.xmu.oomall.customer.microservice.vo.CouponActivityRetVo;
import cn.edu.xmu.oomall.customer.microservice.vo.ProductRetVo;
import cn.edu.xmu.oomall.customer.model.vo.*;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.oomall.customer.dao.CartDao;
import cn.edu.xmu.oomall.customer.model.po.ShoppingCartPo;
import cn.edu.xmu.privilegegateway.annotation.util.InternalReturnObject;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import static cn.edu.xmu.privilegegateway.annotation.util.Common.cloneVo;
import static cn.edu.xmu.privilegegateway.annotation.util.Common.setPoModifiedFields;


@Service
/**
 * @author Haotian Cheng
 * @date 2021-12-14 12:35:06
 * @modifiedBy Jiazhe Yuan
 * @date 2021-12-14 12:35:30
 * @modifiedBy Jiazhe Yuan
 * @time 2021-12-23 11:33:24
 * @info 对接oomall-additional
 */
public class CartService {

    @Autowired
    private CartDao cartDao;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private CouponActivityService couponActivityService;


    @Transactional(rollbackFor = Exception.class)
    public ReturnObject<PageInfo<VoObject>> getCarts(Long customerId, int page, int pageSize) {
        PageHelper.startPage(page, pageSize);
        PageInfo<ShoppingCartPo> shoppingCartPos = cartDao.getCarts(customerId);

        List<VoObject> carts = new ArrayList<>();

        try {
            for (var tmp : shoppingCartPos.getList()) {
                CartRetVo cartRetVo = cloneVo(tmp, CartRetVo.class);
                 InternalReturnObject<ProductRetVo> productDetails = new InternalReturnObject<>();
                try {
                    productDetails = goodsService.getProductDetails(tmp.getProductId());
                } catch (Exception e) {
                    return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR,"getCarts-getProductDetails根据id获取商品失败");
                }
                ProductRetVo productVoInfo = productDetails.getData();
                InternalReturnObject<PageInfo<CouponActivityRetVo>> couponActivityByProductId = new InternalReturnObject<>();
                try {
                    couponActivityByProductId =  couponActivityService.listCouponActivitiesByProductId(tmp.getProductId(), page, pageSize);
                } catch ( Exception e) {
                    System.out.println("in service getCarts");
                    System.out.println(e.getMessage());
                    return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR,"getCarts-listCouponActivitiesByProductId根据pid获取活动列表失败");
                }
                List<SimpleCouponActivityRetVo> list = new ArrayList<>();
                for (var tmp1 : couponActivityByProductId.getData().getList()) {
                    list.add(cloneVo(tmp1, SimpleCouponActivityRetVo.class));
                }
                cartRetVo.setCouponActivity(list);
                cartRetVo.setProduct(cloneVo(productVoInfo, SimpleProductRetVo.class));
                carts.add(cartRetVo);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        PageInfo<VoObject> returnObject = new PageInfo<>(carts);
        returnObject.setPages(shoppingCartPos.getPages());
        returnObject.setPageSize(shoppingCartPos.getPageSize());
        returnObject.setPageNum(shoppingCartPos.getPageNum());
        returnObject.setTotal(shoppingCartPos.getTotal());
        return new ReturnObject<>(returnObject);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject postCarts(Long customerId, String customerName, SimpleCartItemVo simpleCartItemVo) {
        InternalReturnObject<ProductRetVo> product = new InternalReturnObject<>();
        try {
            product = goodsService.getProductDetails(simpleCartItemVo.getProductId());
        } catch (Exception e) {
            System.out.println("in service postCarts");
            System.out.println(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR,"postCarts-getProductDetails根据id获取商品失败");
        }
        ProductRetVo retPro = product.getData();
        var daoRet = cartDao.getCartByPidAndCid(simpleCartItemVo.getProductId(),customerId);
        if (!daoRet.getCode().equals(ReturnNo.OK)) {
            return daoRet;
        }
        //已经添加过购物车
        if (daoRet.getData().size()!=0) {
            ShoppingCartPo exitShoppingCart = daoRet.getData().get(0);
            Long newQuantity = exitShoppingCart.getQuantity()+simpleCartItemVo.getQuantity();
            //小于0将购物车item删除
            if (newQuantity<=0L) {
                var ret3 =  cartDao.deleteCartsById(exitShoppingCart.getCustomerId(),exitShoppingCart.getId());
                if (!ret3.getCode().equals(ReturnNo.OK)) {
                    return ret3;
                }
                return new ReturnObject();
            }
            exitShoppingCart.setQuantity(newQuantity);
            setPoModifiedFields(exitShoppingCart,customerId,customerName);
            var ret2 =  cartDao.updateProductInCartsById(exitShoppingCart);
            if (!ret2.getCode().equals(ReturnNo.OK)) {
                return ret2;
            }
            SimpleCartRetVo simpleCartRetVo = cloneVo(exitShoppingCart, SimpleCartRetVo.class);
            return new ReturnObject(simpleCartRetVo);
        } else {
            ReturnObject ret = cartDao.createNewCartItem(customerId, customerName, retPro, simpleCartItemVo.getQuantity());
            if (!ret.getCode().equals(ReturnNo.OK)) {
                return ret;
            }
            ShoppingCartPo shoppingCartPo = (ShoppingCartPo) ret.getData();
            SimpleCartRetVo simpleCartRetVo = cloneVo(shoppingCartPo, SimpleCartRetVo.class);
            return new ReturnObject<>(simpleCartRetVo);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject deleteCarts(Long customerId) {
        return cartDao.deleteCarts(customerId);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject updateProductInCartsById(Long customerId, String customerName, Long id, SimpleCartItemVo simpleCartItemVo) {
        ShoppingCartPo shoppingCartPo = cloneVo(simpleCartItemVo,ShoppingCartPo.class);
        shoppingCartPo.setCustomerId(customerId);
        shoppingCartPo.setId(id);
        setPoModifiedFields(shoppingCartPo,customerId,customerName);
        return cartDao.updateProductInCartsById(shoppingCartPo);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject deleteProductInCartsById(Long customerId, Long id) {
        return cartDao.deleteCartsById(customerId, id);
    }
}